/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.kelin.calendarlistview;

import com.google.gson.Gson;

import com.kelin.calendarlistview.library.CalendarHelper;
import com.kelin.calendarlistview.library.CalendarListView;
import com.kelin.calendarlistview.net.HttpCallBackListener;
import com.kelin.calendarlistview.net.NetServices;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.WindowManager;

import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

import java.security.SecureRandom;

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.*;

/**
 * CalendarAbilitySlice
 *
 * @since 2021.7.28
 */
public class CalendarAbilitySlice extends AbilitySlice {
    public static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("yyyyMMdd");
    public static final SimpleDateFormat YEAR_MONTH_FORMAT = new SimpleDateFormat("yyyy年MM月");

    private Text mTextTitle;
    private CalendarListView calendarListView;
    private DayNewsListAdapter dayNewsListAdapter;
    private CalendarItemAdapter calendarItemAdapter;
    // key:date "yyyy-mm-dd" format.
    private TreeMap<String, List<News.StoriesBean>> listTreeMap = new TreeMap<>();

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_calendar);
        WindowManager.getInstance().getTopWindow().get().setStatusBarColor(Color.BLACK.getValue());
        WindowManager.getInstance().getTopWindow().get().setStatusBarVisibility(WindowManager.LayoutConfig.SYSTEM_BAR_BRIGHT_STATUS);

        calendarListView = (CalendarListView) findComponentById(ResourceTable.Id_calendar_listview);
        dayNewsListAdapter = new DayNewsListAdapter(getContext());
        calendarItemAdapter = new CalendarItemAdapter(getContext());
        calendarListView.setCalendarListViewAdapter(calendarItemAdapter, dayNewsListAdapter);

        // set start time,just for test.
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -7);
        loadNewsList(DAY_FORMAT.format(calendar.getTime()));
        mTextTitle = (Text) findComponentById(ResourceTable.Id_text_title);
        mTextTitle.setText(YEAR_MONTH_FORMAT.format(calendar.getTime()));

        // deal with refresh and load more event.
        calendarListView.setOnListPullListener(new CalendarListView.onListPullListener() {
            @Override
            public void onRefresh() {
                if (listTreeMap.isEmpty()) {
                    return;
                }
                String date = listTreeMap.firstKey();
                Calendar calendar = CalendarHelper.getCalendarByYearMonthDay(date);
                calendar.add(Calendar.MONTH, -1);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                loadNewsList(DAY_FORMAT.format(calendar.getTime()));
            }

            @Override
            public void onLoadMore() {
                if (listTreeMap.isEmpty()) {
                    return;
                }
                String date = listTreeMap.lastKey();
                Calendar calendar = CalendarHelper.getCalendarByYearMonthDay(date);
                calendar.add(Calendar.MONTH, 1);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                loadNewsList(DAY_FORMAT.format(calendar.getTime()));
            }
        });

        calendarListView.setOnMonthChangedListener(new CalendarListView.OnMonthChangedListener() {
            @Override
            public void onMonthChanged(String yearMonth) {
                Calendar calendar = CalendarHelper.getCalendarByYearMonth(yearMonth);
                mTextTitle.setText(YEAR_MONTH_FORMAT.format(calendar.getTime()));
                loadCalendarData(yearMonth);
                showToast(YEAR_MONTH_FORMAT.format(calendar.getTime()));
            }
        });

        calendarListView.setOnCalendarViewItemClickListener(new CalendarListView.OnCalendarViewItemClickListener() {
            @Override
            public void onDateSelected(Component View, String selectedDate, int listSection, SelectedDateRegion selectedDateRegion) {

            }
        });

        Image btnBack = (Image) findComponentById(ResourceTable.Id_button_back);
        RippleUtil.setComponent(btnBack, 2, 0xAAAAAA);
    }

    private void showToast(String msg) {
        ToastDialog toastDialog = new ToastDialog(getContext());
        Text text = new Text(getContext());
        // 自动换行
        text.setMultipleLine(true);
        text.setText(msg);
        text.setTextSize(14, Text.TextSizeType.FP);
        text.setTextAlignment(TextAlignment.CENTER);
        text.setMarginLeft(225);
        text.setMarginBottom(150);
        text.setPadding(60, 40, 60, 40);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setShaderType(ShapeElement.RECTANGLE);
        shapeElement.setCornerRadius(60);
        // 背景色 可以根据实际需求更改
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.argb(240, 240, 240, 240)));
        text.setBackground(shapeElement);
        toastDialog.setCornerRadius(60f);
        // 设置透明 如果不设置 会有默认白色背景
        toastDialog.setTransparent(true);
        toastDialog.setComponent(text);
        toastDialog.show();
    }

    private void loadNewsList(String date) {
        String key = CalendarHelper.YEAR_MONTH_FORMAT.format(getCalendarByYearMonthDay(date).getTime());

        // just not care about how data to create.
        SecureRandom random = new SecureRandom();
        final List<String> set = new ArrayList<>();
        while (set.size() < 5) {
            int i = random.nextInt(29);
            if (i > 0) {
                if (!set.contains(key + "-" + i)) {
                    if (i < 10) {
                        set.add(key + "-0" + i);
                    } else {
                        set.add(key + "-" + i);
                    }
                }
            }
        }

        String url = null;
        try {
            url = getResourceManager().getElement(ResourceTable.String_news_url).getString();
        } catch (IOException | NotExistException | WrongTypeException ignored) {

        }

        NetServices.getNewsList(url, date, new HttpCallBackListener() {
            @Override
            public void onResponse(String rsp) {
                try {
                    News searchResult = new Gson().fromJson(rsp, News.class);
                    if (searchResult != null) {
                        for (int i = 0; i < searchResult.getStories().size(); i++) {
                            String day = set.get(random.nextInt(5));
                            if (listTreeMap.get(day) != null) {
                                List<News.StoriesBean> list = listTreeMap.get(day);
                                list.add(searchResult.getStories().get(i));
                            } else {
                                List<News.StoriesBean> list = new ArrayList<News.StoriesBean>();
                                list.add(searchResult.getStories().get(i));
                                listTreeMap.put(day, list);
                            }
                        }
                    }
                } catch (Exception ignored) {

                }

                refreshCalendarListView();
            }

            @Override
            public void onFailure(Exception e) {
                refreshCalendarListView();
            }
        });
    }

    private void refreshCalendarListView() {
        if (getAbility() == null) {
            return;
        }
        getUITaskDispatcher().asyncDispatch(() -> {
            if (listTreeMap.size() > 0) {
                dayNewsListAdapter.setDateDataMap(listTreeMap);
                dayNewsListAdapter.notifyDataChanged();
            } else {
                if (calendarListView.getCurrentSelectedDate() == null || calendarListView.getCurrentSelectedDate().isEmpty()) {
                    String date = YEAR_MONTH_FORMAT.format(Calendar.getInstance().getTime());
                    mTextTitle.setText(date);
                    showToast(date);
                }
            }
            calendarItemAdapter.notifyDataChanged();
        });
    }

    private void loadCalendarData(String date) {
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                getUITaskDispatcher().asyncDispatch(() -> {
                    SecureRandom random = new SecureRandom();
                    if (calendarListView.getCurrentSelectedDate() == null) {
                        return;
                    }
                    if (date.equals(calendarListView.getCurrentSelectedDate().substring(0, 7))) {
                        for (String d : listTreeMap.keySet()) {
                            if (date.equals(d.substring(0, 7))) {
                                CustomCalendarItemModel customCalendarItemModel = calendarItemAdapter.getDayModelList().get(d);
                                if (customCalendarItemModel != null) {
                                    customCalendarItemModel.setNewsCount(listTreeMap.get(d).size());
                                    customCalendarItemModel.setFav(random.nextBoolean());
                                }

                            }
                        }
                        calendarItemAdapter.notifyDataChanged();
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    /**
     * getCalendarByYearMonthDay
     *
     * @param yearMonthDay yearMonthDay
     * @return calendar
     */
    public static Calendar getCalendarByYearMonthDay(String yearMonthDay) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTimeInMillis(DAY_FORMAT.parse(yearMonthDay).getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return calendar;
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
